package com.mirror.tk.core.module.sys.service.impl;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.mirror.tk.core.module.sys.cache.SecurityCache;
import com.mirror.tk.core.module.sys.dao.SysResourceDao;
import com.mirror.tk.core.module.sys.domain.SysResource;
import com.mirror.tk.core.module.sys.dto.ResDto;
import com.mirror.tk.core.module.sys.dto.SortInfo;
import com.mirror.tk.core.module.sys.service.SysResourceService;
import com.mirror.tk.framework.common.exception.BusinessException;
import com.mirror.tk.framework.common.service.EntityServiceImpl;

@Service("sysResourceService")
public class SysResourceServiceImpl extends EntityServiceImpl<SysResource, SysResourceDao> implements SysResourceService {

    @Resource
    private SecurityCache securityCache;

    @Override
    public void update(SysResource o) throws BusinessException {
        super.update(o);
        securityCache.clearAllAuthorization();
        securityCache.clearAllMenu();
    }

    @Override
    @Transactional
    public int updateStatusById(Long id, Integer status){
        return super.getEntityDao().updateStatusById(id, status);
    }

    //递归查找
    private void recursionResc(Iterator<SysResource> it, String rescType, Integer status){
        while (it.hasNext()){
            SysResource resc = it.next();

            if((StringUtils.isNotBlank(rescType) && rescType.equals(resc.getResType())==false) || (status!=null && status!=resc.getStatus())){
                it.remove();
            }else if(resc.getSubResource()!=null && resc.getSubResource().size()>=1){
                recursionResc(resc.getSubResource().iterator(), rescType, status);
            }
        }
    }

    @Override
    public List<SysResource> queryByTypeAndStatus(String type, Integer status) {
        Map<String, Object> seachMap = new HashMap<String, Object>();
        Map<String, Boolean> sortMap = new HashMap<String, Boolean>();
        seachMap.put("EQ_parentId", 0);
        if(StringUtils.isNotBlank(type)){
            seachMap.put("EQ_resType", type);
        }
        if(status!=null){
            seachMap.put("EQ_status", status);
        }
        sortMap.put("sortNo", true);
        List<SysResource> list = super.getEntityDao().query(seachMap, sortMap);
        //递归过滤条件
        recursionResc(list.iterator(), type, status);

        return list;
    }

	@Override
	public List<ResDto> toRes(Set<SysResource> res) {
		Set<Long> selected = new HashSet<Long>();
		// 值不为空
		if(null != res){
			for (SysResource r : res) {
				selected.add(r.getId());
			}
		}
		List<SysResource> list = queryByTypeAndStatus(null, 1);
		if(null != list && !list.isEmpty()){
			return toResDto(new ArrayList<SysResource>(list), selected);
		}
		return null;
	}
	
	private List<ResDto> toResDto(List<SysResource> res, Set<Long> selected){
		if(null != res && !res.isEmpty()){
			List<ResDto> list = new ArrayList<ResDto>();
			for (SysResource resource : res) {
				ResDto dto = new ResDto();
				BeanUtils.copyProperties(resource, dto);
				if(selected.contains(resource.getId())){
					dto.setSelected(true);
					selected.remove(resource.getId());
				}
				//如果有子集
				if(!resource.getSubResource().isEmpty()){
					dto.setSubRes(toResDto(new ArrayList<SysResource>(resource.getSubResource()),selected));
				}
				list.add(dto);
			}
			return list;
		}
		return null;
	}

	@Override
	@Transactional
	public int deleteTree(Long id) {
        int count = super.getEntityDao().deleteTree(id);
        securityCache.clearAllMenu();
        return count;
	}

	@Override
	@Transactional
	public void sort(List<SortInfo> sortInfo) {
		for (int i = 0; i < sortInfo.size(); i++) {
			super.getEntityDao().sort(sortInfo.get(i).getId(), Long.valueOf(i+1), sortInfo.get(i).getParentId());
			if(null != sortInfo.get(i).getChildren() && sortInfo.get(i).getChildren().size() > 0){
				sort(sortInfo.get(i).getChildren());
			}
		}
	}

}
